
// benchmark.c (内置完美预取器，用于最终验证)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <time.h>

#define FILENAME "testfile.dat"

// ... (timespec_diff_ms 和 create_test_file 不变) ...
double timespec_diff_ms(struct timespec *start, struct timespec *end) {
    return (end->tv_sec - start->tv_sec) * 1000.0 + (end->tv_nsec - start->tv_nsec) / 1000000.0;
}

void create_test_file(const char *filename, long long file_size) {
    int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) { perror("open"); exit(1); }
    if (ftruncate(fd, file_size) == -1) { perror("ftruncate"); close(fd); exit(1); }
    close(fd);
    printf("Created test file '%s' of size %lld bytes.\n", filename, file_size);
}


int main(int argc, char **argv) {
    if (argc < 3) {
        fprintf(stderr, "Usage: %s <file_size_mb> <stride_kb> [prefetch]\n", argv[0]);
        fprintf(stderr, "Example: ./benchmark 1024 1024         (no prefetch)\n");
        fprintf(stderr, "Example: ./benchmark 1024 1024 prefetch (with prefetch)\n");
        return 1;
    }

    long long file_size = atoll(argv[1]) * 1024 * 1024;
    long stride = atol(argv[2]) * 1024;
    int prefetch_enabled = (argc > 3 && strcmp(argv[3], "prefetch") == 0);

    create_test_file(FILENAME, file_size);
    printf("### TEST CONFIG: Prefetching is %s ###\n", prefetch_enabled ? "ENABLED" : "DISABLED");

    int fd = open(FILENAME, O_RDONLY);
    if (fd == -1) { perror("open"); return 1; }
    
    char *map = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
    if (map == MAP_FAILED) { perror("mmap"); close(fd); return 1; }
    
    volatile char sink = 0;
    
    // *** 最终实验的核心逻辑 ***
    if (prefetch_enabled) {
        printf("Starting prefetch phase (reading whole file sequentially)...\n");
        char *buffer = malloc(4096);
        // 通过顺序读，将整个文件加载到页缓存，模拟完美预取
        while(read(fd, buffer, 4096) > 0);
        free(buffer);
        printf("Prefetch phase finished.\n");
    }

    printf("Starting measurement phase...\n");
    struct timespec start_time, end_time;
    clock_gettime(CLOCK_MONOTONIC, &start_time);

    for (long i = 0; i < file_size; i += stride) {
        sink += map[i]; 
    }
    
    clock_gettime(CLOCK_MONOTONIC, &end_time);
    
    printf("Measurement phase finished. (sink=%d)\n", (int)sink);
    
    double elapsed_ms = timespec_diff_ms(&start_time, &end_time);
    printf("\n>>> MEASUREMENT LOOP TOOK: %.2f ms <<<\n\n", elapsed_ms);

    munmap(map, file_size);
    close(fd);

    return 0;
}